Add new interface for allocating reserved event-channel
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 5 Apr 2006 16:41:51 +0000 (17:41 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 5 Apr 2006 16:41:51 +0000 (17:41 +0100)
ports to arbitrary Xen subsystems.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/common/event_channel.c
xen/include/xen/event.h

index b37a6f183a53b8d7408195b0098b592798b90e29..2f766f7d315a96dd4ab8133980ca7b321d41022b 100644 (file)
@@ -46,6 +46,7 @@
         goto out;                                                   \
     } while ( 0 )
 
+
 static int get_free_port(struct domain *d)
 {
     struct evtchn *chn;
@@ -360,7 +361,7 @@ static long __evtchn_close(struct domain *d1, int port1)
             rc = -EINVAL;
             goto out;
         }
-    
+
         port2 = chn1->u.interdomain.remote_port;
         BUG_ON(!port_is_valid(d2, port2));
 
@@ -438,6 +439,7 @@ long evtchn_send(unsigned int lport)
     return ret;
 }
 
+
 void evtchn_set_pending(struct vcpu *v, int port)
 {
     struct domain *d = v->domain;
@@ -471,6 +473,7 @@ void evtchn_set_pending(struct vcpu *v, int port)
     }
 }
 
+
 void send_guest_virq(struct vcpu *v, int virq)
 {
     int port = v->virq_to_evtchn[virq];
@@ -479,6 +482,7 @@ void send_guest_virq(struct vcpu *v, int virq)
         evtchn_set_pending(v, port);
 }
 
+
 void send_guest_pirq(struct domain *d, int pirq)
 {
     int port = d->pirq_to_evtchn[pirq];
@@ -486,6 +490,7 @@ void send_guest_pirq(struct domain *d, int pirq)
     evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
 }
 
+
 static long evtchn_status(evtchn_status_t *status)
 {
     struct domain   *d;
@@ -550,6 +555,7 @@ static long evtchn_status(evtchn_status_t *status)
     return rc;
 }
 
+
 long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id)
 {
     struct domain *d = current->domain;
@@ -585,6 +591,7 @@ long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id)
     return rc;
 }
 
+
 static long evtchn_unmask(evtchn_unmask_t *unmask)
 {
     struct domain *d = current->domain;
@@ -620,6 +627,7 @@ static long evtchn_unmask(evtchn_unmask_t *unmask)
     return 0;
 }
 
+
 long do_event_channel_op(GUEST_HANDLE(evtchn_op_t) uop)
 {
     long rc;
@@ -694,6 +702,48 @@ long do_event_channel_op(GUEST_HANDLE(evtchn_op_t) uop)
 }
 
 
+int evtchn_open_reserved_port(struct domain *d)
+{
+    struct evtchn *chn;
+    int            port;
+
+    spin_lock(&d->evtchn_lock);
+
+    if ( (port = get_free_port(d)) >= 0 )
+    {
+        chn = evtchn_from_port(d, port);
+        chn->state = ECS_RESERVED;
+    }
+
+    spin_unlock(&d->evtchn_lock);
+
+    return port;
+}
+
+
+void evtchn_close_reserved_port(struct domain *d, int port)
+{
+    struct evtchn *chn;
+
+    spin_lock(&d->evtchn_lock);
+
+    BUG_ON(!port_is_valid(d, port));
+
+    chn = evtchn_from_port(d, port);
+    chn->state          = ECS_FREE;
+    chn->notify_vcpu_id = 0;
+
+    spin_unlock(&d->evtchn_lock);
+}
+
+
+void evtchn_notify_reserved_port(struct domain *d, int port)
+{
+    struct evtchn *chn = evtchn_from_port(d, port);
+    evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
+}
+
+
 int evtchn_init(struct domain *d)
 {
     spin_lock_init(&d->evtchn_lock);
index 8487a25c7bfb2bba6c57145267cdfdacbb50dce5..e56b991406abdcbb0b53b2844a24a79757b2e714 100644 (file)
@@ -45,4 +45,9 @@ extern long evtchn_send(unsigned int lport);
 /* Bind a local event-channel port to the specified VCPU. */
 extern long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);
 
+/* Reserved event-channel ports for other Xen subsystems. */
+int evtchn_open_reserved_port(struct domain *d);
+void evtchn_close_reserved_port(struct domain *d, int port);
+void evtchn_notify_reserved_port(struct domain *d, int port);
+
 #endif /* __XEN_EVENT_H__ */